package com.itheima.proxy;

import com.itheima.service.UserService;
import com.itheima.service.impl.RoleServiceImpl;
import com.itheima.service.impl.UserServiceImpl;
import org.junit.Test;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.MethodInterceptor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyDemo {
    //jdk动态代理
    @Test
    public void test1() {
        //1.创建目标对象
       final UserServiceImpl userServiceImpl=new UserServiceImpl();//com.itheima.service.impl.UserServiceImpl

        //userService.save(11);

        //2.创建代理对象
        /*
        * JDK动态代理是基于接口，代理对象和目标对象要拥有共同接口
        * 涉及的类：Proxy
        * 创建代理对象的方法：newProxyIntance() com.sun.proxy.$Proxy4
        方法下的参数：
        *    1：代理的目标对象的类加载器（固定写法）
        *    2.代理的目标对象可能拥有的接口（固定写法）
        *    3.代理的具体实现
         */
       UserService us = (UserService) Proxy.newProxyInstance(
                userServiceImpl.getClass().getClassLoader(),
                userServiceImpl.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     *
                     * @param proxy 代理对象
                     * @param method 执行目标对象上的方法对象
                     * @param args  执行方法对象的参数列表
                     * @return
                     * @throws Throwable
                     */
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object obj=null;
                        String methodName = method.getName();
                        if ("findAll".equals(methodName)) {
                            obj = method.invoke(userServiceImpl, args); //执行proxy对象上带有args参数的method方法
                        }else {
                            System.out.println("开启事务");
                            obj = method.invoke(userServiceImpl, args);
                        }
                        return obj;
                    }
                });

//       us.findAll();
        us.save(11);
    }

    @Test
    public void test2(){
        //1、目标对象
        final RoleServiceImpl rs=new RoleServiceImpl();

        //2、创建代理对象
        /**
         * Cglib动态代理:基于父类
         *  涉及的类：Enhancer
         *  创建代理对象的方法：create()
         *      方法下的参数：
         *          第一个参数：代理的目标对象的字节码类型（固定写法）
         *          第二个参数：执行代理处理CallBack,使用其子接口MethodInterceptor（拦截执行的方法对象）
         */
        Object rs1 = Enhancer.create(rs.getClass(), new MethodInterceptor() {
            /**
             * @param proxy  代理对象
             * @param method  执行目标对象上的方法对象
             * @param args    执行方法对象的参数列表
             * @return
             * @throws Throwable
             */
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                System.out.println("开启事务");
                return method.invoke(rs,args);
            }
        });
        //rs1.save();
        System.out.println(rs1);
    }
}
